import 'dart:convert';

import 'package:buffer/buffer.dart';
import 'package:flutter/foundation.dart';
import 'package:web_socket_channel/io.dart';
import 'package:web_socket_channel/web_socket_channel.dart';

class LYMessageModel {
  num? slamOrAPP;
  num? msgID;
  num? dataLen;
  dynamic data;
  LYMessageModel({this.slamOrAPP, this.msgID, this.dataLen, this.data});

  LYMessageModel.fromJson(dynamic json) {
    slamOrAPP = json['slamOrAPP'] as num?;
    msgID = json['msgID'] as num?;
    dataLen = json['dataLen'] as num?;
    data = json['data'];
  }
}

class LYWebSocketManager {
  Function(int slamOrAPP, int msgID, int dataLen, dynamic data)? callBack;
  LYWebSocketManager._internal();
  static final LYWebSocketManager _instance = LYWebSocketManager._internal();
  static LYWebSocketManager get share {
    return _instance;
  }

  late WebSocketChannel channel;

  // 创建一个WebSocketChannel，并连接到WebSocket服务器
  void initSocket(
      Function(int slamOrAPP, int msgID, int dataLen, dynamic data)?
          messageCallBack) {
    callBack = messageCallBack;
    _connect();
  }

  void _connect() async {
    // channel = IOWebSocketChannel.connect('ws://124.222.224.186:8800');
    channel = IOWebSocketChannel.connect('ws://192.168.110.126:8080');
    await channel.ready;
    channel.stream.listen(onData, onError: onError, onDone: onDone);
  }

  void sendMessage(int slamOrAPP, int msgID, dynamic content) {
    dynamic msg = LYWebSocketManager.writeDataWithModel(
        LYMessageModel(slamOrAPP: slamOrAPP, msgID: msgID, data: content));
    // msg = jsonEncode(msg);
    try {
      channel.sink.add(msg);
      debugPrint('=====$msg');
    } catch (error) {
      debugPrint('=====$error');
    }
  }

  // socket 链接断开以后重新初始化 socket
  void onDone() async {
    debugPrint("Socket is closed");
    _connect();
  }

  // socket err 情况的处理
  void onError(err) {
    debugPrint(err.runtimeType.toString());
    WebSocketChannelException ex = err;
    debugPrint(ex.message);
  }

  // 收到服务端推送的消息event
  void onData(event) {
    debugPrint('$event');
    // int slamOrAPP, int msgID, int dataLen
    if (event is List<int>) {
      final data = String.fromCharCodes(event);
      final json = jsonDecode(data);
      debugPrint('=======$json');
    } else {}

    // final slamOrAPP = 1;
    // final msgID = 1;
    // final dataLen = 1;
    // final body = null;
    // if (callBack != null) {
    //   callBack!(slamOrAPP, msgID, dataLen, body);
    // }
  }

  // 关闭WebSocket连接
  void dispose() {
    debugPrint('关闭');
    channel.sink.close();
  }

  // 模型数据 --> 二进制数据
  static Uint8List writeDataWithModel(LYMessageModel model) {
    ByteDataWriter contentWrite = ByteDataWriter();
    contentWrite.writeInt32(model.slamOrAPP?.toInt() ?? 0);
    contentWrite.writeInt32(model.msgID?.toInt() ?? 0);
    // List<int> allKeys = model.data.keys.toList();
    // for (int i = 0; i < allKeys.length; i++) {
    //   int key = allKeys[i];
    //   String value = model.body[key];
    //   contentWrite.writeInt32(key);
    //   contentWrite.writeInt32(value.length);
    //   contentWrite.write(value.toString().codeUnits);
    // }
    final json = jsonEncode(model.data);
    contentWrite.writeInt32(json.length);
    contentWrite.write(json.codeUnits);
    return contentWrite.toBytes();
  }
}
